`timescale 1ns / 1ps

`include "defines.vh"

module myCPU (
    input  wire         cpu_rst,
    input  wire         cpu_clk,

    // Interface to IROM
    output wire [15:0]  inst_addr,
    input  wire [31:0]  inst,
    
    // Interface to Bridge
    output wire [31:0]  Bus_addr,
    input  wire [31:0]  Bus_rdata,
    output wire         Bus_wen,
    output wire [31:0]  Bus_wdata

`ifdef RUN_TRACE
    ,// Debug Interface
    output wire         debug_wb_have_inst,
    output wire [31:0]  debug_wb_pc,
    output              debug_wb_ena,
    output wire [ 4:0]  debug_wb_reg,
    output wire [31:0]  debug_wb_value
`endif
);

// TODO: 完成你自己的流水线CPU设计

wire [31:0] inst_addr_temp;
assign inst_addr = inst_addr_temp;
	
// ifetch wires
wire [31:0] pc4;

// idecode wires
wire [1:0] npc_op;
wire [2:0] sext_op;
wire rf_we;
wire [1:0] rf_wsel;
wire alub_sel;
wire [3:0] alu_op;
wire ram_we;
wire [31:0] ext;
wire [31:0] rD1;
wire [31:0] rD2;
wire [31:0] wD;

// execute wires
wire f;
wire [31:0] C;

assign Bus_addr = C;
assign Bus_wen = ram_we;
assign Bus_wdata = rD2;

ifetch ifetch (
	.rst(cpu_rst),
	.clk(cpu_clk),
	.br(f),
	.op(npc_op),
	.offset(ext),
	.radr(rD1),
	.pc4(pc4),
	.pc(inst_addr_temp)
);

control control (
	.funct3(inst[14:12]),
	.funct7(inst[31:25]),
	.opcode(inst[6:0]),
	.npc_op(npc_op),
	.sext_op(sext_op),
	.rf_we(rf_we),
	.rf_wsel(rf_wsel),
	.alub_sel(alub_sel),
	.alu_op(alu_op),
	.ram_we(ram_we)
);

idecode idecode (
	.rst(cpu_rst),
	.clk(cpu_clk),
	.we(rf_we),
	.rf_wsel(rf_wsel),
	.sext_op(sext_op),
	.rdo(Bus_rdata),
	.ALU_C(C),
	.inst(inst),
	.pc4(pc4),
	.ext(ext),
	.rD1(rD1),
	.rD2(rD2),
	.wD(wD)
);

execute execute (
	.alub_sel(alub_sel),
	.alu_op(alu_op),
	.rD1(rD1),
	.rD2(rD2),
	.ext(ext),
	.f(f),
	.C(C)
);


`ifdef RUN_TRACE
    // Debug Interface
    assign debug_wb_have_inst = 1;
    assign debug_wb_pc        = inst_addr_temp;
    assign debug_wb_ena       = rf_we;
    assign debug_wb_reg       = inst[11:7];
    assign debug_wb_value     = wD;
`endif

endmodule
